package api

import (
	"bytes"
	"fmt"
	"github.com/emicklei/go-restful"
	"io"
	"k8s.io/klog"
	"metabank/constants"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
)

type routerHandler struct {
	cache map[string]map[string]string
}

var sanitizer = strings.NewReplacer(`&`, "&amp;", `<`, "&lt;", `>`, "&gt;")

func NewTenantHandler(caches map[string]map[string]string) *routerHandler {
	return &routerHandler{
		cache: caches,
	}
}

func (r routerHandler) getrouter(req *restful.Request, resp *restful.Response) {

	svcName := req.QueryParameter("serviceName")
	cusNum := req.PathParameter("customerNumber")
	if len(cusNum) < 2 {
		resp.WriteAsJson(map[string]string{"serviceIP": ""})
		return
	}
	sliceNum := cusNum[len(cusNum)-2:]
	idc := r.cache[constants.SliceKey][sliceNum]
	destServiceIP := r.cache[idc][svcName]

	resp.WriteAsJson(map[string]string{"serviceIP": destServiceIP})
}

func (r routerHandler) upload(request *restful.Request, resp *restful.Response) {

	if _, err := os.Stat(constants.InstallYamlPath); os.IsNotExist(err) {
		os.Mkdir(constants.InstallYamlPath, os.ModePerm)
	}

	req := request.Request
	err := req.ParseMultipartForm(10 << 20)
	if err != nil {
		handle(http.StatusBadRequest, resp, err)
		return
	}
	for fName := range req.MultipartForm.File {
		file, header, err := req.FormFile(fName)
		if err != nil {
			handle(http.StatusBadRequest, resp, err)
			return
		}

		defer file.Close()
		filePath := path.Join(constants.InstallYamlPath, header.Filename)

		f, err := os.Create(filePath)

		if err != nil {
			handle(http.StatusBadRequest, resp, err)
			return
		}
		defer f.Close()
		io.Copy(f, file)
		err = installMcpResource(filePath)
		if err != nil {
			handle(http.StatusBadRequest, resp, err)
			return
		}
	}
	resp.WriteAsJson(map[string]string{"status": "success"})

}

func installMcpResource(yamlPaht string) error {
	stdout := &bytes.Buffer{}
	stderr := &bytes.Buffer{}
	cmd := exec.Cmd{
		Path:   constants.KubectlCmdPath,
		Stdout: stdout,
		Stderr: stderr,
	}

	cmd.Args = make([]string, 0, 10)
	cmd.Args = append(cmd.Args, constants.KubectlCmdPath)
	cmd.Args = append(cmd.Args, "apply", "-f")
	cmd.Args = append(cmd.Args, yamlPaht)
	cmd.Args = append(cmd.Args, "--kubeconfig", filepath.Join(constants.ConfigPath, constants.McpConfigName))
	err := cmd.Run()
	if err != nil {
		klog.Errorf("deploy mcp resource run command: %s failed, stderr: %s, error: %v", cmd.String(), stderr, err)
		return fmt.Errorf("%s", stderr.String())
	} else {
		klog.V(2).Infof("deploy mcp resource run command success, stdout: %s", stdout)
	}
	return nil
}

func handle(statusCode int, response *restful.Response, err error) {
	_, fn, line, _ := runtime.Caller(2)
	klog.Errorf("%s:%d %v", fn, line, err)
	http.Error(response, sanitizer.Replace(err.Error()), statusCode)
}
